package pt.iul.poo.monkeys;

import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;

import pt.iul.poo.balloons.Balloon;
import pt.iul.poo.game.Player;
import pt.iul.poo.image.SimpleImage;
import pt.iul.poo.image.properties.DisplayableElement;
import pt.iul.poo.image.properties.GameWindowInterface;
import pt.iul.poo.shapes.SimpleShape;
import pt.iul.poo.weapon.Weapons;

public abstract class Monkey {
	private MonkeyTypes type = null;
	private int range;
	private Weapons weapon = null;
	private SimpleImage simpleImage;
	

	public Monkey(String fileName, int x, int y, int range) throws IOException {
		setSimpleImage(new SimpleImage(fileName, x, y));
		this.setWeapon(weapon);
		this.setRange(range);
	}

	public void shoot(LinkedList<Balloon> balloonsList, Player player,
			GameWindowInterface window, Weapons weapon,
			LinkedList<SimpleShape> shapesList, ArrayList<Balloon> ballonsToRemove) {
		balloonsList = selectRangeBallons(balloonsList);
		if (!balloonsList.isEmpty()) {
			Balloon balloon = balloonsList.getFirst();
			weapon.shoot(balloon, window, this, shapesList);
			weapon.removeLife(balloon, balloonsList, player, ballonsToRemove);
		}
	}

	private LinkedList<Balloon> selectRangeBallons(LinkedList<Balloon >balloonsList) {
		LinkedList<Balloon> temp = new LinkedList<Balloon>();
		for (Balloon each : balloonsList) {
			if (range(this, each) <= getRange()) {
				temp.add(each);
			}
		}
		return temp;
	}

	public static int range(Monkey monkey, Balloon balloon) {
		double range = Math.abs(monkey.getSimpleImage().getPosition().distance(balloon.getPosition())
				/ monkey.getSimpleImage().getDimension().width);
		double fractionalPart = range % 1;
		return (int) (range - fractionalPart);
	}

	public abstract String getName();

	public MonkeyTypes getType() {
		return type;
	}

	public void setType(MonkeyTypes type) {
		this.type = type;
	}

	public LinkedList<Balloon> getBallonsWithinRange(
			LinkedList<Balloon> balloonsList) {
		LinkedList<Balloon> temporaryList = new LinkedList<>();
		for (Balloon balloon : balloonsList) {
			if (Math.abs(getSimpleImage().getPosition().distance(balloon.getPosition())) < getRange()) {
				temporaryList.add(balloon);
			}
		}
		return balloonsList;

	}

	public int getRange() {
		return range;
	}

	public void setRange(int range) {
		this.range = range;
	}

	public Weapons getWeapon() {
		return weapon;
	}

	public void setWeapon(Weapons weapon) {
		this.weapon = weapon;
	}

	public Point2D getPosition() {
		return getSimpleImage().getPosition();
	}

	public Dimension getDimension() {
		return getSimpleImage().getDimension();
	}

	public DisplayableElement getImage() {
		return getSimpleImage();
	}

	public SimpleImage getSimpleImage() {
		return simpleImage;
	}

	public void setSimpleImage(SimpleImage simpleImage) {
		this.simpleImage = simpleImage;
	}
}